package jtmcraft.game.units.states;

import java.util.Random;
import jtmcraft.game.units.CollisionManager;
import jtmcraft.game.units.GameUnit;
import jtmcraft.graphics.Sprite;

/**
 *
 * @author milosz
 */
public class AttackState extends MovableState {

    GameUnit enemy;
    int sleepCount = 0;
    Random rm;

    public AttackState(GameUnit enemy) {
        this.enemy = enemy;
        this.rm = new Random();
    }

    public void update(GameUnit gameUnit, long timestamp) {

        if( !enemy.isLive() ) {
            gameUnit.setState( new MoveState( enemy.getMidX(), enemy.getMidY() ) );
        }

        int dx = enemy.getX() + enemy.getWidth() / 2 - (gameUnit.getWidth() / 2) - gameUnit.getX();
        int dy = enemy.getY() + enemy.getHeight() / 2 - (gameUnit.getHeight() / 2) - gameUnit.getY();

        if (dx == 0 && dy == 0) {
            return;
        }

        double dr = Math.sqrt(dx * dx + dy * dy);

        double i = dx / dr;
        double j = dy / dr;

        double sx = (i * .05 * timestamp);
        double sy = (j * .05 * timestamp);

        //to jes s
        if (Math.abs(sx) > Math.abs(dx)) {
            gameUnit.setX(gameUnit.getX() + (int) dx);
            gameUnit.setY(gameUnit.getY() + (int) dy);

            return;
        }

        int newX = gameUnit.getX() + (int) sx;
        int newY = gameUnit.getY() + (int) sy;

        double katRadian = Math.asin(j);

        Sprite sprite = gameUnit.getSprite();

        setMoveAction(sprite, katRadian, i);


        /// wczesniejsze mozna wydzielic

        GameUnit collisionUnit = CollisionManager.getInstance().checkCollision(newX, newY, gameUnit);

        if (null == collisionUnit) {
            gameUnit.setX(newX);
            gameUnit.setY(newY);
            return;
        }

        if (collisionUnit == enemy) {
            setAttackAction( gameUnit.getSprite(), katRadian, i );
            gameUnit.getActionHandler().attack( gameUnit, enemy, katRadian, i );
            if( sleepCount > 0 ) {
                sleepCount--;
            } else {
                sleepCount = 50;
                gameUnit.getActionHandler().hit( gameUnit, enemy, rm.nextInt(Math.abs(gameUnit.getMaxDescrution())) );
            }
            return;
        }

        //jezeli nie to omijamy

            for (int n = 45; n < 360; n += 45) {
                int prX = (int) (sx * Math.cos(Math.toRadians(n)) - sy * Math.sin(Math.toRadians(n)));
                int prY = (int) (sx * Math.sin(Math.toRadians(n)) + sy * Math.cos(Math.toRadians(n)));
                // remap to new position
                newX = prX + gameUnit.getX(); // slight speed up to avoid deadlock
                newY = prY + gameUnit.getY(); // slight speed up to avoid deadlock
                if (null == CollisionManager.getInstance().checkCollision(newX, newY, gameUnit)) {
                    gameUnit.setX(newX);
                    gameUnit.setY(newY);

                    dr = Math.sqrt(prX * prX + prY * prY);
                    i = prX / dr;
                    j = prY / dr;
                    katRadian = Math.asin(j);
                    setMoveAction(sprite, katRadian, i);

                    break;
                }
            }
    }

    private void setAttackAction(Sprite sprite, double degree, double i) {
        int direction = (int) (degree / (Math.PI / 8));
        if (i >= 0) {
            switch (direction) {
                case 0:
                    sprite.setSpriteAction(Sprite.eSpriteAction.attackE);
                    break;
                case -1:
                case -2:
                    sprite.setSpriteAction(Sprite.eSpriteAction.attackNE);
                    break;
                case -3:
                    sprite.setSpriteAction(Sprite.eSpriteAction.attackN);
                    break;
                case 1:
                case 2:
                    sprite.setSpriteAction(Sprite.eSpriteAction.attackSE);
                    break;
                case 3:
                    sprite.setSpriteAction(Sprite.eSpriteAction.attackS);
                    break;
            }
        }
        if (i < 0) {
            switch (direction) {
                case 0:
                    sprite.setSpriteAction(Sprite.eSpriteAction.attackW);
                    break;
                case -1:
                case -2:
                    sprite.setSpriteAction(Sprite.eSpriteAction.attackWN);
                    break;
                case -3:
                    sprite.setSpriteAction(Sprite.eSpriteAction.attackN);
                    break;
                case 1:
                case 2:
                    sprite.setSpriteAction(Sprite.eSpriteAction.attackSW);
                    break;
                case 3:
                    sprite.setSpriteAction(Sprite.eSpriteAction.attackS);
                    break;
            }
        }
    }

}
